23.07.11
오늘 한 일
- Gloddy 개발(상세 페이지)
- TIL GA 재연결, Docsearch 연결
- Rust 스터디 진행
추상화 수준
함수형 프로그래밍 공부를 하면서 배웠던 개념 중 계층형 설계
가 있다.
추상화 벽을 통해 세부적인 것을 감추고, 추상화된 것을 통해 더 큰 것을 만들어 나가는 것이다.
함수형 프로그래밍 뿐만 아니라, 클린 코드
책에서도 이렇게 설명하고 있다.
3장 함수
- 작게 만들어라!
- 한 가지만 해라!
- 함수 당 추상화 수준은 하나로!
위에서 아래로 코드 읽기: 내려가기 규칙
코드는 위에서 아래로 이야기처럼 읽혀야 좋다. 즉, 함수 추상화 수준이 한 번에 한 단계씩 낮아진다.
핵심은 짧으면서도 '한 가지'만 하는 함수다. 위에서 아래로 TO 문단을 읽어내려 가듯이 코드를 구현하면 추상화 수준을 일관되게 유지하기가 쉬워진다.
이 개념을 프로젝트에 적용해보고 싶었다.
나는 이런 식으로 구분했다.
추상화 수준이 낮다는 것은 디테일이 많이 드러났다는 것
높은 추상화 수준
- 페이지 컴포넌트보통 추상화 수준
- 섹션 컴포넌트낮은 추상화 수준
- 일반 컴포넌트
페이지 컴포넌트에서는 추상화된 컴포넌트를 가져와 페이지의 구조를 직관적으로 파악할 수 있도록 하고, 추상화된 컴포넌트 안에서는 세부적인 것을 구현하도록 하였다.
만약 한 컴포넌트에서 추상화 수준이 다르다면, 그 컴포넌트는 더 작은 컴포넌트로 분리해야 한다.
예시
다음은 진유림님의 토스ㅣSLASH 21 - 실무에서 바로 쓰는 Frontend Clean Code
에서 나왔던 예시다.
Gloddy 프로젝트에서도 적용해보자
Gloddy 프로젝트에서도 이 개념을 적용해보았다.
export default function DetailPage({
params: { id },
}: {
params: {
id: string;
};
}) {
const { image, title, description, location, time } = DETAIL_DUMMY_DATA;
return (
<main>
<TopNavigationBar />
<TopSection id={id} title={title} thumbnailUrl={image} description={description} />
<div className="p-20 pb-100">
<MemberSection />
<Spacing size={18} />
<TimeSection time={time} />
<Spacing size={18} />
<LocationSection location={location} />
</div>
<ApplyButton />
</main>
);
}
이렇게 페이지 컴포넌트에서는 추상화된 컴포넌트를 가져와 페이지의 구조를 직관적으로 파악할 수 있도록 하였다.
Next13의 App Router를 사용하고 있는데 어떻게 서버 컴포넌트와 클라이언트 컴포넌트를 분리할 지 고민이었다.
위 방식대로 구현하면 페이지 컴포넌트를 서버 컴포넌트로 하고, 추상화된 컴포넌트는 상황에 따라 클라이언트 컴포넌트로 분리할 수 있을 것 같다.
Rust 스터디
8시 부터 9시 반까지 Rust 스터디를 진행했다.
String vs str
String
은 Vec
과 같은 dynamic heap string 타입이다.
str
은 메모리 어딘가에 있는 가변 길이의 UTF-8 바이트로 구성된 불변 시퀀스이다.
크기를 알 수 없어서 포인터 뒤에서만 처리할 수 있다. 일반적으로 string slice
또는 그냥 slice
라고 불리는 UTF-8 데이터에 대한 참조인 &str
타입으로 사용된다.
slice는 데이터를 읽는 용도로만 사용할 수 있기 때문에 해당 데이터는 어디에 있든지 상관없다.
메모리 어딘가에 있다고 했는데, 상황에 따라 힙, 스택, 또는 바이너리에 있을 수 있다.
static storage
: "hello world"라는 문자열 리터럴은&'static str
타입이다. 이는 프로그램이 실행되는 동안에는 항상 메모리에 존재한다는 것을 의미한다.heap
에 할당된String
내부: String은 String의 데이터에 대한 &str로 역참조된다.
fn takes_str(s: &str) { }
let s = String::from("Hello");
takes_str(&s);
String
으로부터 &str
가 만들어지고 takes_str
함수에 전달된다.
stack
: 스택에 할당된 바이트 배열을 만들고 그 데이터를 가리키는&str
을 만들 수 있다.
use std::str;
let x: &[u8] = &[b'a', b'b', b'c'];
let stack_str: &str = str::from_utf8(x).unwrap();
참고
What are the differences between Rust's String
and str
?
내일 할 일
- CS 스터디 정리
- Gloddy 개발
- 오후 2시 데일리 스크럼
- 오후 10시 30분 프로그라피 회의